#region FileHeader
//////////////////////////////////////////////////////////////////////////////////
// Author:                          Hector Llanos
// Date:                            08.27.2010
// FileName:                        ObjectManager.cs
// Reason:                           Wrapper to create multiple objects
//////////////////////////////////////////////////////////////////////////////////
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Base;
using Objects;

namespace Manager
{
    public class Pair<T, U>
    {
        public Pair()
        {
        }

        public Pair(T first, U second)
        {
            this.First = first;
            this.Second = second;
        }

        public T First { get; set; }
        public U Second { get; set; }
    };

    public sealed class ObjectFactory<IDtype, BaseClassName>
    {
        // Function pointer declaration   
        private delegate BaseClassName ObjectCreator();

        // Database of function pointes to create objects
        
        private Dictionary<IDtype, ObjectCreator> m_ObjectCreators;

        /// <summary>
        /// Make this class a singleton
        /// </summary>
        private static ObjectFactory<IDtype, BaseClassName> m_instance = new ObjectFactory<IDtype,BaseClassName>();
      

        public static ObjectFactory<IDtype, BaseClassName> Instance
        {
            get
            {
                return  m_instance;
            }

        }
    
        private ObjectFactory( )
        {
            m_ObjectCreators = new Dictionary<IDtype, ObjectCreator>();
        }


        //Private function to create an object
        private static BaseClassName ConstructObject<DerivedClassType>() where DerivedClassType : BaseClassName, new()
        {
            return new DerivedClassType();
        }
 
        public bool RegisterClassType<DerivedClassType>(IDtype id) where DerivedClassType : BaseClassName, new()
        {
            ObjectCreator objectFunctor = ConstructObject<DerivedClassType>;
            m_ObjectCreators.Add(id, objectFunctor);
     

            return true;
        }

        public bool UnRegisterClassType(IDtype id)
        {
            if (m_ObjectCreators.ContainsKey(id))
            {
                m_ObjectCreators.Remove(id);
                return true;
            }
            else
                return false;
        }
        //if the id is not there, it will crash
        // i need to add an assert or try catch block
        public BaseClassName CreateObject(IDtype id)
        {
            ObjectCreator createFunctor = m_ObjectCreators[id];
                 return createFunctor(); 
        }

        public void ShutdownObjectFactory()
        {
            m_ObjectCreators.Clear();
        }
    }
}